package top.lyjwn.todo.weinxin.mch.pay.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.lyjwn.todo.common.model.LogE;
import top.lyjwn.todo.common.component.InfLogHandle;
import top.lyjwn.todo.common.utils.XMLUtil;
import top.lyjwn.todo.weinxin.api.url.WXPayUrl;
import top.lyjwn.todo.weinxin.data.mch.*;
import top.lyjwn.todo.weinxin.data.mch.param.*;
import top.lyjwn.todo.weinxin.mch.pay.WXPay;
import top.lyjwn.todo.weinxin.param.WXPayParam;
import top.lyjwn.todo.common.utils.http.HttpUtil;
import top.lyjwn.todo.weinxin.utils.SSLUilt;

import java.util.Date;

/**
 * 微信支付接口的实现
 *
 * @author luoyujie
 */
@Component("wxPay")
public class WXPayImpl implements WXPay {


    private static Logger logger = LoggerFactory.getLogger(WXPayImpl.class);

    @Autowired(required = false)
    private InfLogHandle infLogHandle;

    @Autowired
    private WXPayParam wxPayParam;

    @Autowired
    private SSLUilt sslUilt;

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.pay.WXPay#unifiedOrderApi(top.lyjwn.todo.weinxin.pay.
     * param.UnifiedOrder)
     */
    @Override
    public UnifiedOrderResult unifiedOrderApi(UnifiedOrder unifiedOrder) {
        String xml = XMLUtil.convertToXml(unifiedOrder);
        LogE logE = new LogE();
        logE.setKeyWord(unifiedOrder.getOut_trade_no() + "," + unifiedOrder.getAttach() + "," + unifiedOrder.getOpenid());
        logE.setInfNme("unifiedOrder");
        logE.setRequestTime(new Date());
        String request = HttpUtil.request(WXPayUrl.UNIFIED_ORDER, "POST", xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        UnifiedOrderResult result = XMLUtil.convertXmlStrToObject(UnifiedOrderResult.class, request);
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#queryOrderApi(top.lyjwn.todo.weinxin.mch
     * .pay.param.QueryOrder)
     */
    @Override
    public QueryOrderResult queryOrderApi(QueryOrder queryOrder) {
        String xml = XMLUtil.convertToXml(queryOrder);
        LogE logE = new LogE();
        logE.setKeyWord(queryOrder.getOut_trade_no() + "," + queryOrder.getTransaction_id());
        logE.setInfNme("queryOrder");
        logE.setRequestTime(new Date());
        String request = HttpUtil.request(WXPayUrl.QUERY_ORDER, "POST", xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        QueryOrderResult result = XMLUtil.convertXmlStrToObject(QueryOrderResult.class, request);
        return result.replenish();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#closeOrderApi(top.lyjwn.todo.weinxin.mch
     * .pay.param.CloseOrder)
     */
    @Override
    public CloseOrderResult closeOrderApi(CloseOrder closeOrder) {
        String xml = XMLUtil.convertToXml(closeOrder);
        LogE logE = new LogE();
        logE.setKeyWord(closeOrder.getOut_trade_no());
        logE.setInfNme("closeOrder");
        logE.setRequestTime(new Date());
        String request = HttpUtil.request(WXPayUrl.CLOSE_ORDER, "POST", xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        CloseOrderResult result = XMLUtil.convertXmlStrToObject(CloseOrderResult.class, request);
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#applyRefundApi(top.lyjwn.todo.weinxin.
     * mch.pay.param.ApplyRefund)
     */
    @Override
    public ApplyRefundResult applyRefundApi(ApplyRefund applyRefund) {
        String xml = XMLUtil.convertToXml(applyRefund);
        LogE logE = new LogE();
        logE.setKeyWord(applyRefund.getOut_trade_no() + "," + applyRefund.getOut_refund_no() + "," + applyRefund.getTransaction_id() + "," + applyRefund.getRefund_desc());
        logE.setInfNme("applyRefund");
        logE.setRequestTime(new Date());
        String request = sslUilt.wxPayRequest(WXPayUrl.APPLY_REFUND, xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        ApplyRefundResult result = XMLUtil.convertXmlStrToObject(ApplyRefundResult.class, request);
        return result.replenish();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#queryRefund(top.lyjwn.todo.weinxin.mch.
     * pay.param.QueryOrder)
     */
    @Override
    public QueryRefundResult queryRefundApi(QueryRefund queryRefund) {
        String xml = XMLUtil.convertToXml(queryRefund);
        LogE logE = new LogE();
        logE.setKeyWord(queryRefund.getOut_trade_no() + "," + queryRefund.getOut_refund_no() + "," + queryRefund.getTransaction_id());
        logE.setInfNme("queryRefund");
        logE.setRequestTime(new Date());
        String request = HttpUtil.request(WXPayUrl.QUERY_REFUND, "POST", xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        int offset = 0;
        if (queryRefund.getOffset() != null) {
            try {
                offset = Integer.parseInt(queryRefund.getOffset());
            } catch (Exception e) {
                logger.error("微信查询退款：转换偏移量错误 --:" + e.getMessage());
            }
        }

        QueryRefundResult result = XMLUtil.convertXmlStrToObject(QueryRefundResult.class, request);
        return result.replenish();
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#downloadBillApi(top.lyjwn.todo.weinxin.
     * mch.pay.param.DownloadBill)
     */
    @Override
    public DownloadBillResult downloadBillApi(DownloadBill downloadBill) {
        String xml = XMLUtil.convertToXml(downloadBill);
        LogE logE = new LogE();
        logE.setInfNme("downloadBill");
        logE.setRequestTime(new Date());
        String request = HttpUtil.request(WXPayUrl.DOWNLOAD_BILL, "POST", xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        DownloadBillResult result;
        if (request.contains("交易时间") || (!request.contains("return_code") && !request.contains("RETURN_CODE"))) {
            result = new DownloadBillResult();
            result.setBody(request);
            return result;
        }
        result = XMLUtil.convertXmlStrToObject(DownloadBillResult.class, request);
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see top.lyjwn.todo.weinxin.mch.pay.WXPay#downloadFundFlowApi(top.lyjwn.todo.
     * weinxin.mch.pay.param.DownloadFundFlow)
     */
    @Override
    public DownloadFundFlowResult downloadFundFlowApi(DownloadFundFlow downloadFundFlow) {
        String xml = XMLUtil.convertToXml(downloadFundFlow);
        LogE logE = new LogE();
        logE.setInfNme("downloadFundFlow");
        logE.setRequestTime(new Date());
        String request = sslUilt.wxPayRequest(WXPayUrl.DOWNLOAD_BILL, xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        DownloadFundFlowResult result = XMLUtil.convertXmlStrToObject(DownloadFundFlowResult.class, request);
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#reportApi(top.lyjwn.todo.weinxin.mch.pay
     * .param.Report)
     */
    @Override
    public ReportResult reportApi(Report report) {
        String xml = XMLUtil.convertToXml(report);
        LogE logE = new LogE();
        logE.setInfNme("report");
        logE.setRequestTime(new Date());
        String request = HttpUtil.request(WXPayUrl.REPORT_API_ELAPSED, "POST", xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        ReportResult result = XMLUtil.convertXmlStrToObject(ReportResult.class, request);
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * top.lyjwn.todo.weinxin.mch.pay.WXPay#batchQueryCommentApi(top.lyjwn.todo.
     * weinxin.mch.pay.param.BatchQueryComment)
     */
    @Override
    public BatchQueryCommentResult batchQueryCommentApi(BatchQueryComment batchQueryComment) {
        String xml = XMLUtil.convertToXml(batchQueryComment);
        LogE logE = new LogE();
        logE.setInfNme("batchQueryComment");
        logE.setRequestTime(new Date());
        String request = sslUilt.wxPayRequest(WXPayUrl.BATCH_QUERY_COMMENT, xml);
        logE.setResponseTime(new Date());
        logE.setInputParam(xml);
        logE.setOutputParam(request);
        if (infLogHandle != null) {
            infLogHandle.write(logE);
        }
        BatchQueryCommentResult result = XMLUtil.convertXmlStrToObject(BatchQueryCommentResult.class, request);
        return result;
    }

}
